var javadox = function() {

	var doc_list = {
		'jdk-6u10'                     : 'docs/jdk-6u10',
		'hadoop-0.20.1'                : 'docs/hadoop-0.20.1',
		'hbase-0.20.1'                 : 'docs/hbase-0.20.1',
		'zookeeper-3.2.1'              : 'docs/zookeeper-3.2.1',
		'zookeeper-3.3.x-devel'        : 'docs/zookeeper-3.3.x-devel',
		'codi-20100723'                : 'docs/codi-20100723',
		'codi-20100914'                : 'docs/codi-20100914',
		'apache-cli2-trunk-r887508'    : 'docs/apache-cli2-trunk-r887508',
		'apache-commons-cli-1.2'       : 'docs/apache-commons-cli-1.2',
		'apache-commons-codec-1.3'     : 'docs/apache-commons-codec-1.3',
		'apache-commons-el-1.0'        : 'docs/apache-commons-el-1.0',
		'apache-commons-exec-1.0.1'    : 'docs/apache-commons-exec-1.0.1',
		'apache-commons-httpclient-3.1': 'docs/apache-commons-httpclient-3.1',
		'apache-commons-io-1.4'        : 'docs/apache-commons-io-1.4',
		'apache-commons-math-1.1'      : 'docs/apache-commons-math-1.1',
		'apache-commons-net-2.0'       : 'docs/apache-commons-net-2.0',
		'apache-log4j-1.2.15'          : 'docs/apache-log4j-1.2.15',
		'appengine-20101014'           : 'docs/appengine-20101014',
		'google-gson-1.5'              : 'docs/google-gson-1.5',
		'jdo-1.1'                      : 'docs/jdo-1.1',
		'jdo-2.2'                      : 'docs/jdo-2.2',
		'jdo-3.0'                      : 'docs/jdo-3.0',
		'jetty-6.1.14'                 : 'docs/jetty-6.1.14',
		'jms-1.1'                      : 'docs/jms-1.1',
		'junit-3.8.1'                  : 'docs/junit-3.8.1',
		'junit-4.7'                    : 'docs/junit-4.7',
		'quartz-1.6.6'                 : 'docs/quartz-1.6.6',
		'rhino-1.7r2'                  : 'docs/rhino-1.7r2',
		'spring-3.0.0'                 : 'docs/spring-3.0.0-api',
		'xmlenc-0.52'                  : 'docs/xmlenc-0.52',
		'xstream-1.3.1'                : 'docs/xstream-1.3.1',
	};

	var man_list = {
		'spring-3.0.0' : 'docs/spring-3.0.0-doc',
	};

	var prj_list = {
		'demo': {
			'desc': 'GMS (Global Meta Store)',
			'docs': [
				'jdk-6u10',
				'hadoop-0.20.1',
				'hbase-0.20.1',
//				'zookeeper-3.2.1',
				'zookeeper-3.3.x-devel',
				'codi-20100723',
				'codi-20100914',
				'apache-cli2-trunk-r887508',
				'apache-commons-cli-1.2',
				'apache-commons-codec-1.3',
				'apache-commons-el-1.0',
				'apache-commons-exec-1.0.1',
				'apache-commons-httpclient-3.1',
				'apache-commons-io-1.4',
				'apache-commons-math-1.1',
				'apache-commons-net-2.0',
				'apache-log4j-1.2.15',
				'appengine-20101014',
				'google-gson-1.5',
				'jdo-1.1',
				'jdo-2.2',
				'jdo-3.0',
				'jetty-6.1.14',
				'jms-1.1',
				'junit-3.8.1',
				'junit-4.7',
				'quartz-1.6.6',
				'rhino-1.7r2',
				'spring-3.0.0',
				'xmlenc-0.52',
				'xstream-1.3.1',
			],
			'mans': [
				'spring-3.0.0',
			],
		},
		'test': {
			'desc': 'test project',
			'docs': [
				'jdk-6u10',
//				'junit-3.8.1',
			],
		},
	};

	var doc_cache = {};

	function javadox_html_fix(html) {
		var p = html.indexOf('<!-- =========== END OF NAVBAR =========== -->');
		if (p < 0) {
			p = html.indexOf('<!-- ========= END OF TOP NAVBAR ========= -->');
		}
		html = html.substr(p);
		p = html.indexOf('<!-- ========== START OF NAVBAR ========== -->');
		if (p < 0) {
			p = html.indexOf('<!-- ======= START OF BOTTOM NAVBAR ====== -->');
		}
		html = html.substr(0, p);
		p = html.lastIndexOf('<HR>');
		if (p >= 0) {
			html = html.substr(0, p);
		}
		p = html.indexOf('<HR>');
		if (p >= 0) {
			html = html.substr(p + 4);
		}
		html = html.replace(/ CELLPADDING="[^"]*"/g, '');
		html = html.replace(/ CELLSPACING="[^"]*"/g, '');
		html = html.replace(/ WIDTH="[^"]*"/g, '');
		html = html.replace(/ BGCOLOR="[^"]*"/g, '');
//		html = html.replace(/<\/?B>/g, '');
		html = html.replace(/<\/?FONT[^>]*>/g, '');
		html = html.replace(/<\s*div\s+style="[^"]*"\s*>/ig, '<div>');
//		$('textarea.dox-debug-area').text(html);
		return html;
	}

	var current_classes_url = ''; // XXX: temporary hack

	function javadox_dom_fix($frame, doc_name) {
		if (doc_list[doc_name]) {
			var ubase = doc_list[doc_name];
			$frame.find('a').each(function() {
				var $a = $(this);
				if ($a.attr('href') && !$a.attr('href').match(/^(http|https):\/\//)) {
					$a.attr('href', $a.attr('href').replace(/^(\.\.\/)*/, ubase + '/'));
				}
			});
			$frame.find('blockquote > pre').each(function() {
				var $blockquote = $(this).parent('blockquote');
				$blockquote.replaceWith($blockquote.contents());
			});
			$frame.find('a').bind('click', function() {
				var $a = $(this);
				var url = $a.attr('href');
				var pfrag = url.indexOf('#');
				var $frag = null;
				if (pfrag >= 0) {
					var frag = url.substr(pfrag + 1);
					url = url.substr(0, pfrag);
					var pqstr = frag.indexOf('?');
					if (pqstr >= 0) {
						frag = frag.substr(0, pqstr);
					}
					$frag = $frame.find('a[name=' + frag + ']');
				}
				if (url != current_classes_url) {
					javadox_get_page(url, function(page) {
//						$('textarea.dox-debug-area').text(page);
						javadox_dom_fix($frame.html(page), doc_name);
						$('textarea.dox-debug-area').text($frame.html());
						$.scrollTo(($frag ? $frag : 0), {axis:'y'});
					});
				}
				else {
					$.scrollTo($frag ? $frag : 0, {axis:'y'});
				}
				return false;
			});
		}
	}

	function javadox_get_page(url, callback) {
		if (doc_cache['pages'] && doc_cache['pages'][url]) {
			callback(doc_cache['pages'][url]);
		}
		else {
			$.get(url, {}, function(data, textStatus) {
				if (!doc_cache['pages']) {
					doc_cache['pages'] = {};
				}
				doc_cache['pages'][url] = javadox_html_fix(data);
//				$('textarea.dox-debug-area').text(doc_cache['pages'][url]);
				callback(doc_cache['pages'][url]);
			});
		}
		current_classes_url = url;
	}
	
	function javadox_for_package_tree(doc_name, callback) {
		if (doc_cache['tree'] && doc_cache['tree'][doc_name]) {
			callback(doc_cache['tree'][doc_name]);
		}
		if (doc_list[doc_name]) {
			var ubase = doc_list[doc_name];
			$.get(ubase + '/package-list', {}, function(data, textStatus) {
				if (!doc_cache['tree']) {
					doc_cache['tree'] = {};
				}
				if (!doc_cache['tree'][doc_name]) {
					doc_cache['tree'][doc_name] = {};
				}
				$.each(data.split(/\n/), function() {
					var pkg_name = $.trim(''+this);
					if (pkg_name.length > 0) {
						doc_cache['tree'][doc_name][pkg_name] = {};
					}
				});
				$.get(ubase + '/allclasses-frame.html', {}, function(data, textStatus) {
					var ab = 0;
					while ((ab = data.indexOf('<A HREF="', ab)) >= 0) {
						ab += 9;
						var ae = data.indexOf('"', ab);
						if (ae >= 0) {
							var href = data.substr(ab, ae - ab);
							var spec = href.substr(0, href.indexOf('.html')).split('/');
							var name = spec.join('.');
							var clss = spec.pop();     // class name
							var pack = spec.join('.'); // package name
							if ((clss.length > 0) && (pack.length > 0)) {
								doc_cache['tree'][doc_name][pack][clss] = {};
							}
						}
					} // while (ab)
					callback(doc_cache['tree'][doc_name]);
				});
			});
		}
	}

	function setup_dox_matrix(matrix_selector) {
		$(matrix_selector).append(
			'<table><tr><th class="ui-widget-header">Document \ Project</th></tr></table>'
		);

		$.each(prj_list, function(prj_name, info) {
			$(matrix_selector + ' table tr:first').append(
				$('<th/>').addClass('ui-widget-header').append(
					$('<a/>').attr('href', 'javascript://')
					         .attr('title', info['desc'])
					         .text(prj_name.toUpperCase())
				)
			);
		});
		$.each(doc_list, function(doc_name, url) {
//			url = url.replace(/\/?$/, "/");
			var tr = $('<tr/>').append(
				$('<td/>')
				.addClass('ui-widget-header')
				.append($('<a/>').attr('href', url + '/index.html').text(doc_name))
			);
			$.each(prj_list, function(prj_name, info){
				var td = $('<td/>').addClass('ui-widget-content');
				if ($.inArray(doc_name, info['docs']) >= 0) {
					td.append(
						$('<a/>').attr('href', url).text('view')
					)
				}
				tr.append(td);
			});
			$(matrix_selector + ' table').append(tr);
		});
	}

	function setup_project_tabs() {
		$.each(prj_list, function(prj_name, info) {
			var prj_name_css = prj_name.toLowerCase().replace(/\./g, '-');
			// add tab
			$('#dox-tabs ul:first').append(
				$('<li/>').addClass('ui-state-default ui-corner-top').append(
					$('<a/>').attr('href', '#dox-tab-' + prj_name_css)
					         .text(prj_name)
				)
			);
			// add pane
			$('#dox-tabs').append(
				$('<div/>')
				.attr('id', 'dox-tab-' + prj_name_css)
				.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')
			);
		});
	}

	return {
		'initialize': function() {
			setup_dox_matrix('#dox-matrix');
			setup_project_tabs();
		
			$('span.dox-treenode-mark').live('click', function() {
				var me = $(this);
				var ul = me.nextAll('ul');
				ul.toggle('fast', function() {
					me.html(
						(ul.css('display') == 'none') ? '&#x229E;'/*+*/
						                              : '&#x229F;'/*-*/
					);
				});
			});
		
			$('#dox-tabs').tabs({
				show: function(evt, ui) {
					var prj_name = $(ui.tab).text();
					if (prj_name != 'Javadox') {
						var $panel = $(ui.panel);
						if ($panel.find('textarea.dox-debug-area').length == 0) {
							$panel.append($('<textarea/>').addClass('dox-debug-area'));
						}
						if ($panel.find('div.dox-navbar-frame').length == 0) {
							$panel.append(
								$('<div/>')
								.addClass('dox-navbar-frame ui-corner-all')
								.append($('<span/>').addClass('ui-icon ui-icon-circle-arrow-w'))
								.append($('<span/>').addClass('ui-icon ui-icon-circle-arrow-e'))
							);
						}
						if ($panel.find('div.dox-packages-frame').length == 0) {
							$panel.append(
								$('<div/>')
								.addClass('dox-packages-frame ui-corner-all').
								append($('<ul/>'))
							);
							$.each(prj_list[prj_name]['docs'], function() {
								var doc_name = $.trim(''+this);
								if (doc_list[doc_name]) {
									var doc_name_css = 'dox-doc-' + doc_name.replace(/\./g, '_');
									var ul0 = $panel.find('div.dox-packages-frame > ul');
									var li0 = $('<li/>');
									li0.append(
										$('<span/>')
										.addClass('dox-treenode-mark')
										.html('&#x229E;')
									).append(
										$('<span/>')
										.addClass('dox-treenode-link')
										.addClass(doc_name_css)
										.text(doc_name)
										.bind('click', function() {
											javadox_get_page(doc_list[doc_name] + '/overview-summary.html', function(overview) {
//												$('textarea.dox-debug-area').text(overview);
												var $frame = $panel.find('div.dox-classes-frame');
												javadox_dom_fix($frame.html(overview), doc_name);
												$('textarea.dox-debug-area').text($frame.html());
											});
										})
									).appendTo(ul0);
									var ul1 = $('<ul/>').css('display', 'none').appendTo(li0);
									javadox_for_package_tree(doc_name, function(tree) {
										$.each(tree, function (pkg_name, classes) {
											var pkg_name_css = 'dox-pkg-' + pkg_name.replace(/\./g, '-');
											var li1 = $('<li/>');
											li1.append(
												$('<span/>')
												.addClass('dox-treenode-mark')
												.html('&#x229E;')
											).append(
												$('<span/>')
												.addClass('dox-treenode-link')
												.addClass(pkg_name_css)
												.text(pkg_name)
												.bind('click', function() {
													var url = doc_list[doc_name] + '/'
													        + pkg_name.split(/\./).join('/')
													        + '/package-summary.html';
													javadox_get_page(url, function(pkg_html) {
//														$('textarea.dox-debug-area').text(pkg_html);
														var $frame = $panel.find('div.dox-classes-frame');
														javadox_dom_fix($frame.html(pkg_html), doc_name);
														$('textarea.dox-debug-area').text($frame.html());
													});
												})
											).appendTo(ul1);
											var ul2 = $('<ul/>').appendTo(li1);
											ul2.css('display', 'none'); // initial hidden
											$.each(classes, function(cls_name, cls_info) {
												ul2.append(
													$('<li/>').append(
														$('<span/>')
														.addClass('dox-treenode-link')
														.text(cls_name)
														.bind('click', function() {
															var url = doc_list[doc_name] + '/'
															        + pkg_name.split(/\./).join('/')
															        + '/' + cls_name + '.html';
															javadox_get_page(url, function(cls_html) {
//																$('textarea.dox-debug-area').text(cls_html);
																var $frame = $panel.find('div.dox-classes-frame');
																javadox_dom_fix($frame.html(cls_html), doc_name);
																$('textarea.dox-debug-area').text($frame.html());
															})
														})
													)
												);
											});
										});
									});
								}
							});
						}
						if ($panel.find('div.dox-classes-frame').length == 0) {
							$panel.append($('<div/>').addClass('dox-classes-frame'));
							javadox_get_page(doc_list[prj_list[prj_name]['docs'][0]] + '/overview-summary.html', function(overview) {
//								$('textarea.dox-debug-area').text(overview);
								$frame = $panel.find('div.dox-classes-frame');
								javadox_dom_fix($frame.html(overview), prj_list[prj_name]['docs'][0]);
								$('textarea.dox-debug-area').text($frame.html());
							});
						}
						if ($panel.find('div.dox-clear-frame').length == 0) {
							$panel.append($('<div/>').addClass('dox-clear-frame').append($('<hr/>')));
						}
					}
				},
			});
		}, // function 'initialize'
	};
}();

